home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / xvisrc.zip / TERMCAP.C < prev    next >
C/C++ Source or Header  |  1992-07-28  |  26KB  |  1,139 lines

  1. /* Copyright (c) 1990,1991,1992 Chris and John Downey */
  2. #ifndef lint
  3. static char *sccsid = "@(#)termcap.c    2.1 (Chris & John Downey) 7/29/92";
  4. #endif
  5.  
  6. /***
  7.  
  8. * program name:
  9.     xvi
  10. * function:
  11.     PD version of UNIX "vi" editor, with extensions.
  12. * module name:
  13.     termcap.c
  14. * module function:
  15.     Termcap terminal interface module.
  16.  
  17.     The following capabilities are not yet used, but may be added in future
  18.     to improve efficiency (at the expense of code compactness):
  19.  
  20.     cr    str    Carriage return, (default ^M)
  21.     dC    num    Number of milliseconds of cr delay needed
  22.     nc    bool    No correctly working carriage return (DM2500,H2000)
  23.     xr    bool    Return acts like ce \r \n (Delta Data)
  24.  
  25.     ch    str    Like cm but horizontal motion only, line stays same
  26.     DO    str    down N lines
  27.     up    str    Upline (cursor up)
  28.     UP    str    up N lines
  29.     LE    str    left N chars
  30.     RI    str    right N spaces
  31.     ll    str    Last line, first column
  32.     sc    str    save cursor
  33.     rc    str    restore cursor from last "sc"
  34.     dB    num    Number of milliseconds of bs delay needed
  35.  
  36.     AL    str    add N new blank lines
  37.     DL    str    delete N lines
  38.  
  39.     dc    str    Delete character
  40.     dm    str    Delete mode (enter)
  41.     ed    str    End delete mode
  42.     ip    str    Insert pad after character inserted
  43.     in    bool    Insert mode distinguishes nulls on display
  44.     mi    bool    Safe to move while in insert mode
  45.  
  46.     dF    num    Number of milliseconds of ff delay needed
  47.     cd    str    Clear to end of display
  48.  
  49.     xs    bool    Standout not erased by writing over it (HP 264?)
  50.     ms    bool    Safe to move while in standout and underline mode
  51.  
  52. * history:
  53.     STEVIE - ST Editor for VI Enthusiasts, Version 3.10
  54.     Originally by Tim Thompson (twitch!tjt)
  55.     Extensive modifications by Tony Andrews (onecom!wldrdg!tony)
  56.     Heavily modified by Chris & John Downey
  57.  
  58. ***/
  59.  
  60. #include "xvi.h"
  61.  
  62. /* #define    SG_TEST    1 */
  63.  
  64. static    void    xyupdate P((void));
  65. static    void    fail P((char *));
  66. static    void    set_scroll_region P((int, int));
  67.  
  68. /*
  69.  * These are used to optimise output - they hold the current
  70.  * "real" and "virtual" coordinates of the cursor, i.e. where
  71.  * it is and where it is supposed to be.
  72.  *
  73.  * The "optimise" variable says whether we should cache cursor
  74.  * positions or should just go to the place asked; it is
  75.  * unset at the start so that the first goto sets things up.
  76.  *
  77.  * Note that the functions "outchar" and "outstr" should be
  78.  * used for strings of ordinary characters; stdio primitives
  79.  * are used internally to put out escape sequences.
  80.  */
  81. static    int    real_row = 0, real_col = 0;
  82. static    int    virt_row = 0, virt_col = 0;
  83. static    bool_t    optimise = FALSE;
  84.  
  85. /*
  86.  * Termcap-related declarations.
  87.  */
  88. extern    char    *tgetstr();
  89. extern    char    *tgoto();
  90.  
  91. /*
  92.  * Exported.
  93.  */
  94. int        cost_goto = 0;        /* cost of doing a goto */
  95. bool_t        can_scroll_area = FALSE; /* true if we can set scroll region */
  96. bool_t        can_del_line;        /* true if we can delete lines */
  97. bool_t        can_ins_line;        /* true if we can insert lines */
  98. bool_t        can_inschar;        /* true if we can insert characters */
  99. unsigned int    CO = 0;            /* screen dimensions; 0 at start */
  100. unsigned int    LI = 0;
  101.  
  102. /*
  103.  * Needed by termcap library.
  104.  */
  105. char    PC;                /* pad character */
  106.  
  107. /*
  108.  * Internal string, num and boolean defs.
  109.  */
  110. static    char    *KS, *KE;        /* keypad transmit start/end */
  111. static    char    *VS, *VE;        /* visual start/end */
  112. static    char    *TI, *TE;        /* cursor motion start/end */
  113. static    char    *CE, *CL;        /* erase line/display */
  114. static    char    *AL, *DL;        /* insert/delete line */
  115. static    char    *IC, *IM, *EI;        /* insert character / insert mode */
  116. static    char    *CM;            /* cursor motion string */
  117. static    char    *HO;            /* cursor to home position */
  118. static    char    *CS;            /* change scroll region */
  119. static    char    *sf, *sr;        /* scroll forward/reverse 1 line */
  120. static    char    *SF, *SR;        /* scroll forward/reverse n lines */
  121. static    char    *SO, *SE;        /* standout mode start/end */
  122.  
  123. static    char    *VB;            /* visual bell */
  124.  
  125. static    char    *colours[10];        /* colour caps c0 .. c9 */
  126. static    int    ncolours;        /* number of colour caps we have */
  127.  
  128. static    char    BC;            /* backspace char */
  129. static    char    ND;            /* backspace char */
  130. static    char    DO;            /* down one line */
  131.  
  132. static    bool_t    can_backspace;        /* true if can backspace (bs/bc) */
  133. static    bool_t    can_fwdspace = FALSE;    /* true if can forward space (nd) */
  134. static    bool_t    can_movedown = FALSE;    /* true if can move down (do) */
  135. static    bool_t    auto_margins;        /* true if AM is set */
  136.  
  137. /*
  138.  * We use this table to perform mappings from cursor keys
  139.  * into appropriate xvi input keys (in command mode).
  140.  */
  141. static char arrow_keys[] = {
  142.     K_UARROW,    '\0',
  143.     K_DARROW,    '\0',
  144.     K_RARROW,    '\0',
  145.     K_LARROW,    '\0',
  146.     CTRL('B'),    '\0',
  147.     CTRL('F'),    '\0',
  148.     K_HELP,    '\0',
  149. };
  150. static struct {
  151.     char    *key_tcname;
  152.     char    *key_rhs;
  153. } keys[] = {
  154.     "ku",    arrow_keys + 0,    /* up */
  155.     "kd",    arrow_keys + 2,    /* down */
  156.     "kr",    arrow_keys + 4,    /* right */
  157.     "kl",    arrow_keys + 6,    /* left */
  158.     "kP",    arrow_keys + 8,    /* page up */
  159.     "kN",    arrow_keys + 10,/* page down */
  160.     "kh",    "H",        /* home */
  161.     "k0",    "#0",        /* function key 0 */
  162.     "k1",    arrow_keys + 12,/* help */
  163.     "k2",    "#2",        /* function key 2 */
  164.     "k3",    "#3",        /* function key 3 */
  165.     "k4",    "#4",        /* function key 4 */
  166.     "k5",    "#5",        /* function key 5 */
  167.     "k6",    "#6",        /* function key 6 */
  168.     "k7",    "#7",        /* function key 7 */
  169.     "k8",    "#8",        /* function key 8 */
  170.     "k9",    "#9",        /* function key 9 */
  171.     NULL
  172. };
  173.  
  174. /*
  175.  * Standout glitch: number of spaces left when entering or leaving
  176.  * standout mode.
  177.  *
  178.  * This abomination is still needed for some terminals (e.g.
  179.  * Televideo).
  180.  */
  181. int        SG;
  182.  
  183. /*
  184.  * Used by scroll region optimisation.
  185.  */
  186. static int    s_top = 0, s_bottom = 0;
  187.  
  188. /*
  189.  * Used for colour-setting optimisation.
  190.  */
  191. #define    NO_COLOUR    -1
  192. static    int        old_colour = NO_COLOUR;
  193.  
  194. /*
  195.  * Flush any pending output, including cursor position.
  196.  */
  197. void
  198. flush_output()
  199. {
  200.     xyupdate();
  201.     oflush();
  202. }
  203.  
  204. /*
  205.  * Put out a "normal" character, updating the cursor position.
  206.  */
  207. void
  208. outchar(c)
  209. register int    c;
  210. {
  211.     xyupdate();
  212.     real_col++;
  213.     virt_col++;
  214.     if (real_col >= CO) {
  215.     if (auto_margins) {
  216.         virt_col = (real_col = 0);
  217.         virt_row = (real_row += 1);
  218.     } else {
  219.         optimise = FALSE;
  220.     }
  221.     }
  222.     moutch(c);
  223. }
  224.  
  225. /*
  226.  * Put out a "normal" string, updating the cursor position.
  227.  */
  228. void
  229. outstr(s)
  230. register char    *s;
  231. {
  232.     xyupdate();
  233.     while (*s != '\0') {
  234.     real_col++;
  235.     virt_col++;
  236.     moutch(*s++);
  237.     }
  238.  
  239.     /*
  240.      * We only worry about whether we have hit the right-hand margin
  241.      * at the end of the string; this is okay so long as we can trust
  242.      * the calling code not to use outstr if the string is going to
  243.      * wrap around.
  244.      */
  245.     if (real_col >= CO) {
  246.     if (auto_margins) {
  247.         virt_col = (real_col %= CO);
  248.         virt_row = (real_row += 1);
  249.     } else {
  250.         optimise = FALSE;
  251.     }
  252.     }
  253. }
  254.  
  255. /*
  256.  * This routine is called by tty_open() if for some reason the terminal
  257.  * is unsuitable.
  258.  */
  259. static void
  260. fail(str)
  261. char    *str;
  262. {
  263.     /*
  264.      * Assume we are in raw mode already, so set back into cooked.
  265.      */
  266.     sys_endv();
  267.  
  268.     (void) fputs(str, stderr);
  269.     putc('\n', stderr);
  270.  
  271.     exit(2);
  272. }
  273.  
  274. /*
  275.  * Look up term entry in termcap database, and set up all the strings.
  276.  */
  277. void
  278. tty_open(prows, pcolumns)
  279. unsigned int    *prows;
  280. unsigned int    *pcolumns;
  281. {
  282.     char    tcbuf[1024];        /* buffer for termcap entry */
  283.     char    *termtype;        /* terminal type */
  284.     static    char strings[512];    /* space for storing strings */
  285.     char    *strp = strings;    /* ptr to space left in strings */
  286.     char    *cp;            /* temp for single char strings */
  287.     int    i;
  288.  
  289.     termtype = getenv("TERM");
  290.     if (termtype == NULL) {
  291.     fail("Can't find your terminal type.");
  292.     }
  293.     switch (tgetent(tcbuf, termtype)) {
  294.     case -1:
  295.     fail("Can't open termcap.");
  296.     /*NOTREACHED*/
  297.     case 0:
  298.     fail("Can't find entry for your terminal in termcap.");
  299.     /*NOTREACHED*/
  300.     }
  301.  
  302.     /*
  303.      * Booleans.
  304.      */
  305.     auto_margins = (bool_t) (tgetflag("am") && !tgetflag("xn"));
  306.     can_backspace = (bool_t) tgetflag("bs");
  307.  
  308.     /*
  309.      * Integers.
  310.      */
  311.  
  312.     /*
  313.      * Screen dimensions. Ask termcap for its values if we haven't
  314.      * already got any.
  315.      */
  316.     if (*pcolumns == 0) {
  317.     int iv;
  318.  
  319.     iv = tgetnum("co");
  320.     if (iv <= 0) {
  321.         fail("`co' entry in termcap is invalid or missing.");
  322.     }
  323.     *pcolumns = CO = (unsigned) iv;
  324.     } else {
  325.     CO = *pcolumns;
  326.     }
  327.     if (*prows ==